#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
VFS与clouds_client整合模块
提供云盘存储与VFS的无缝整合
"""

import os
import sys
import io
import logging
from typing import Optional, BinaryIO, Dict, Any, List
from datetime import datetime

# 添加项目根目录到路径
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
if project_root not in sys.path:
    sys.path.insert(0, project_root)

from .virtual_file_system import VirtualFileSystem
from .VFSClient import VFSClient
from src.clouds_sdk.cloud_manager import get_cloud_manager
from src.models.storage import VirtualStorage


class CloudVFSIntegration:
    """云盘VFS整合类"""
    
    def __init__(self, vfs_client: VFSClient):
        """
        初始化云盘VFS整合
        
        Args:
            vfs_client: VFS客户端实例
        """
        self.vfs_client = vfs_client
        self.cloud_manager = get_cloud_manager()
        self.logger = logging.getLogger(__name__)
        
        # 确保云盘管理器已初始化
        if not self.cloud_manager.is_initialized():
            self.cloud_manager.initialize()
    
    def upload_to_cloud_and_vfs(self, file_stream: BinaryIO, vfs_path: str, 
                                provider: str = 'tianyi_pc', username: str = None,
                                overwrite: bool = True, **meta) -> int:
        """
        上传文件到云盘并在VFS中创建引用
        
        Args:
            file_stream: 文件流
            vfs_path: VFS路径
            provider: 云盘提供商
            username: 用户名（如果为None则使用第一个可用账号）
            overwrite: 是否覆盖现有文件
            **meta: 附加元数据
            
        Returns:
            int: 0表示成功
        """
        try:
            # 获取用户名
            if username is None:
                accounts = self.cloud_manager.list_loaded_accounts()
                if not accounts:
                    raise ValueError("没有可用的云盘账号")
                username = accounts[0]['username'].split('_')[-1]  # 提取实际用户名
            
            # 读取文件内容
            if hasattr(file_stream, 'read'):
                file_content = file_stream.read()
                if hasattr(file_stream, 'seek'):
                    file_stream.seek(0)  # 重置流位置
            else:
                file_content = file_stream
            
            # 上传到云盘
            clouds_client = self.cloud_manager.clouds_client
            
            # 生成云盘路径（可以根据需要自定义路径映射策略）
            cloud_path = self._map_vfs_to_cloud_path(vfs_path)
            
            # 上传文件
            upload_success = clouds_client.upload_file(
                provider=provider,
                username=username,
                file_stream=io.BytesIO(file_content) if isinstance(file_content, bytes) else file_content,
                remote_path=cloud_path
            )
            
            if not upload_success:
                raise Exception("云盘上传失败")
            
            self.logger.info(f"文件已上传到云盘: {provider}:{username}:{cloud_path}")
            
            # 在VFS中创建文件引用
            # 添加云盘相关的元数据
            cloud_meta = {
                'cloud_provider': provider,
                'cloud_username': username,
                'cloud_path': cloud_path,
                'storage_type': 'cloud',
                **meta
            }
            
            # 使用VFS上传（这会创建本地存储和虚拟文件记录）
            result = self.vfs_client.upload_file(
                file_stream=io.BytesIO(file_content) if isinstance(file_content, bytes) else file_content,
                vfs_path=vfs_path,
                overwrite=overwrite,
                **cloud_meta
            )
            
            self.logger.info(f"文件已在VFS中创建引用: {vfs_path}")
            return result
            
        except Exception as e:
            self.logger.error(f"上传文件到云盘和VFS失败: {e}")
            raise
    
    def download_from_cloud_or_vfs(self, vfs_path: str) -> BinaryIO:
        """
        从云盘或VFS下载文件
        优先从本地VFS获取，如果失败则从云盘下载
        
        Args:
            vfs_path: VFS路径
            
        Returns:
            BinaryIO: 文件流
        """
        try:
            # 首先尝试从VFS获取
            try:
                return self.vfs_client.download_file_stream(vfs_path)
            except Exception as vfs_error:
                self.logger.warning(f"从VFS下载失败，尝试从云盘下载: {vfs_error}")
            
            # 获取文件信息以确定云盘位置
            file_info = self.vfs_client.stat(vfs_path)
            
            cloud_provider = file_info.get('cloud_provider')
            cloud_username = file_info.get('cloud_username')
            cloud_path = file_info.get('cloud_path')
            
            if not all([cloud_provider, cloud_username, cloud_path]):
                raise ValueError("文件缺少云盘信息，无法从云盘下载")
            
            # 从云盘下载
            clouds_client = self.cloud_manager.clouds_client
            cloud_stream = clouds_client.download_file_stream(
                provider=cloud_provider,
                username=cloud_username,
                remote_path=cloud_path
            )
            
            self.logger.info(f"文件已从云盘下载: {cloud_provider}:{cloud_username}:{cloud_path}")
            return cloud_stream
            
        except Exception as e:
            self.logger.error(f"下载文件失败: {e}")
            raise
    
    def sync_cloud_to_vfs(self, provider: str = 'tianyi_pc', username: str = None,
                         cloud_path: str = '/', vfs_base_path: str = '/cloud_sync') -> int:
        """
        同步云盘文件到VFS
        
        Args:
            provider: 云盘提供商
            username: 用户名
            cloud_path: 云盘路径
            vfs_base_path: VFS基础路径
            
        Returns:
            int: 同步的文件数量
        """
        try:
            # 获取用户名
            if username is None:
                accounts = self.cloud_manager.list_loaded_accounts()
                if not accounts:
                    raise ValueError("没有可用的云盘账号")
                username = accounts[0]['username'].split('_')[-1]
            
            clouds_client = self.cloud_manager.clouds_client
            
            # 获取云盘文件列表
            cloud_files = clouds_client.ls(provider, username, cloud_path)
            
            synced_count = 0
            
            for file_info in cloud_files:
                try:
                    if file_info.get('is_dir'):
                        # 递归同步文件夹
                        sub_cloud_path = f"{cloud_path.rstrip('/')}/{file_info['name']}"
                        sub_vfs_path = f"{vfs_base_path.rstrip('/')}/{file_info['name']}"
                        
                        # 创建VFS目录
                        self.vfs_client.mkdir(sub_vfs_path)
                        
                        # 递归同步
                        sub_count = self.sync_cloud_to_vfs(
                            provider=provider,
                            username=username,
                            cloud_path=sub_cloud_path,
                            vfs_base_path=sub_vfs_path
                        )
                        synced_count += sub_count
                    else:
                        # 同步文件
                        file_cloud_path = f"{cloud_path.rstrip('/')}/{file_info['name']}"
                        file_vfs_path = f"{vfs_base_path.rstrip('/')}/{file_info['name']}"
                        
                        # 检查VFS中是否已存在
                        if self.vfs_client.exists(file_vfs_path):
                            self.logger.debug(f"文件已存在，跳过: {file_vfs_path}")
                            continue
                        
                        # 下载文件并上传到VFS
                        cloud_stream = clouds_client.download_file_stream(
                            provider=provider,
                            username=username,
                            remote_path=file_cloud_path
                        )
                        
                        # 添加云盘元数据
                        meta = {
                            'cloud_provider': provider,
                            'cloud_username': username,
                            'cloud_path': file_cloud_path,
                            'storage_type': 'cloud',
                            'synced_at': datetime.now().isoformat()
                        }
                        
                        # 上传到VFS
                        self.vfs_client.upload_file(
                            file_stream=cloud_stream,
                            vfs_path=file_vfs_path,
                            overwrite=False,
                            **meta
                        )
                        
                        synced_count += 1
                        self.logger.info(f"文件同步成功: {file_cloud_path} -> {file_vfs_path}")
                        
                except Exception as e:
                    self.logger.error(f"同步文件失败 {file_info.get('name', 'Unknown')}: {e}")
                    continue
            
            self.logger.info(f"云盘同步完成，共同步 {synced_count} 个文件")
            return synced_count
            
        except Exception as e:
            self.logger.error(f"同步云盘到VFS失败: {e}")
            raise
    
    def get_cloud_file_info(self, vfs_path: str) -> Optional[Dict[str, Any]]:
        """
        获取VFS文件对应的云盘信息
        
        Args:
            vfs_path: VFS路径
            
        Returns:
            Optional[Dict]: 云盘文件信息
        """
        try:
            file_info = self.vfs_client.stat(vfs_path)
            
            cloud_provider = file_info.get('cloud_provider')
            cloud_username = file_info.get('cloud_username')
            cloud_path = file_info.get('cloud_path')
            
            if not all([cloud_provider, cloud_username, cloud_path]):
                return None
            
            clouds_client = self.cloud_manager.clouds_client
            cloud_info = clouds_client.stat(cloud_provider, cloud_username, cloud_path)
            
            return {
                'vfs_info': file_info,
                'cloud_info': cloud_info,
                'cloud_provider': cloud_provider,
                'cloud_username': cloud_username,
                'cloud_path': cloud_path
            }
            
        except Exception as e:
            self.logger.error(f"获取云盘文件信息失败: {e}")
            return None
    
    def _map_vfs_to_cloud_path(self, vfs_path: str) -> str:
        """
        将VFS路径映射到云盘路径
        可以根据需要自定义映射策略
        
        Args:
            vfs_path: VFS路径
            
        Returns:
            str: 云盘路径
        """
        # 简单映射：在云盘中创建vfs_files目录
        if vfs_path.startswith('/'):
            return f"/vfs_files{vfs_path}"
        else:
            return f"/vfs_files/{vfs_path}"
    
    def list_cloud_accounts(self) -> List[Dict[str, str]]:
        """列出可用的云盘账号"""
        return self.cloud_manager.list_loaded_accounts()
    
    def get_cloud_account_info(self, provider: str = 'tianyi_pc', username: str = None) -> Optional[Dict[str, Any]]:
        """获取云盘账号信息"""
        if username is None:
            accounts = self.list_cloud_accounts()
            if not accounts:
                return None
            username = accounts[0]['username'].split('_')[-1]
        
        return self.cloud_manager.get_account_info(username)


def create_cloud_vfs_client(vfs_client: Optional[VFSClient] = None) -> CloudVFSIntegration:
    """
    创建云盘VFS整合客户端
    
    Args:
        vfs_client: VFS客户端实例，如果为None则创建默认实例
        
    Returns:
        CloudVFSIntegration: 整合客户端
    """
    if vfs_client is None:
        from src.common.database import init_global_session
        
        # 初始化全局session
        init_global_session()
        
        # 创建VFS实例
        vfs_core = VirtualFileSystem()
        vfs_client = VFSClient(vfs_core)
    
    return CloudVFSIntegration(vfs_client)